<?php
/*
 * @Author: CHINAKAIYUAN<sunkaiyuan@namenode.cn>
 * @Date: 2022-02-04 16:53:56
 * @LastEditTime: 2023-07-31 10:11:22
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @Description: 
 */

namespace App\Http\Services\Market;

use App\Events\UploadFileEvent;
use App\Http\Services\Service;
use App\Models\Attachment;
use App\Repositories\CompanyLinkManRepository;
use App\Repositories\MarketOfferPromotionsRepository;
use App\Repositories\MarketOfferRepository;
use App\Repositories\MarketOrderDetailsRepository;
use App\Repositories\MarketOrderRepository;
use App\Repositories\MarketOrderSaleRepository;
use App\Repositories\MarketOrderSelfRepository;

/**
 * @property MarketOrderRepository          $repository
 * @property MarketOrderDetailsRepository   $details
 * @property CompanyLinkManRepository       $linkman
 * @property MarketOrderSaleRepository      $sale_repository
 * @property MarketOrderSelfRepository      $self_repository
 * @property MarketOfferPromotionsRepository      $promotion
 * @property MarketOfferRepository      $offer
 */
class OrderService extends Service
    {
    public $details;
    public function boot(
        MarketOrderRepository $repository,
        MarketOrderDetailsRepository $details,
        CompanyLinkManRepository $linkman,
        MarketOrderSaleRepository $sale_repository,
        MarketOrderSelfRepository $self_repository,
        MarketOfferRepository $offer,
        MarketOfferPromotionsRepository $promotion
    ) {
        $this->repository      = $repository;
        $this->details         = $details;
        $this->linkman         = $linkman;
        $this->sale_repository = $sale_repository;
        $this->self_repository = $self_repository;
        $this->offer           = $offer;
        $this->promotion       = $promotion;
        }

    public function list()
        {
        $data = $this->repository->condition(request())->getGrid();
        return $data;
        }
    public function details()
        {
        $data = $this->details->condition(request())->getGrid();
        return $data;
        }
    protected function save($request)
        {
        $data = $request->toArray();
        if ($data['state_id'] == 2)
            $repository = $this->sale_repository;
        else if ($data['state_id'] == 1)
            $repository = $this->repository;
        else
            $repository = $this->self_repository;

        $id = is_numeric($data['id'] ?? "") ? $data['id'] : 0;
        if ($id !== 0) {
            $gdata = $repository->whereId($id)->getOne();
            if ($gdata->status_id != '0') {
                fail("订单状态[{$gdata->status->name}],禁止编辑");
                }
            }
        //保存联系人
        if (!is_numeric($data['linkman_id'] ?? "") && is_array($data['linkman'])) {
            $data['linkman']['company_id'] = $data['customer_id'];
            $data['linkman_id']            = $this->linkman->autosave($data['linkman'])->id;
            }
        //合计订单包/重
        $quantity = $auxiliary_quantity = $amount = 0;

        $data['details'] = array_map(function ($v) use (&$quantity, &$auxiliary_quantity, &$amount, $data)
            {
            $quantity += $v['quantity'];
            $amount += $v['amount'];

            $auxiliary_quantity += $v['auxiliary_quantity'];
            $v['delivery_quantity'] = $v['plan_quantity'] = $v['quantity']; //可交货，可计划数量赋值
            $v['process_route_id'] = $data['process_route_id'];

            if (isEmpty($v['material_id'])) {
                fail("物料不能为空！");
                }
            if (isEmpty($v['color_id'])) {
                fail("颜色不能为空！");
                }
            if (!is_numeric($v['auxiliary_quantity']) || $v['auxiliary_quantity'] <= 0) {
                fail("打包数不能为空或小于等于0！");
                }
            if (!is_numeric($v['quantity']) || $v['quantity'] <= 0) {
                fail("订单数不能为空或小于等于0！");
                }

            if ((!is_numeric($v['price']) || $v['price'] < 0) && $data['state_id'] != 3) {
                fail("d单价不能为空或小于等于0！");
                }
            return $v;
            }, $data['details']);
        //可交货，可计划数量赋值
        $data['delivery_quantity']  = $data['plan_quantity'] = $data['quantity'] = $quantity;
        $data['auxiliary_quantity'] = $auxiliary_quantity;
        $data['amount']             = $amount;

        $data = $repository->autosave($data);
        if ($data->details->count() == 0) {
            fail("明细不能为空！");
            }
        $data->details->filter(function ($v) use ($data)
            {
            $v->offer_code = $this->offer->mate($v->material_id, 7)?->code;
            //匹配优惠卷
            $promotion = $this->promotion->mate(
                $data->state_id == 1 ? 2 : 1,
                0,
                $v->material_id,
                $v->color,
                $data->customer,
                $v->quantity
            );
            if ($promotion->count() > 0) {
                $v->promotion_code = $promotion->first()->code;
                }
            $v->is_export = $data->is_export;
            $v->save();
            });
        return $data;
        }
    protected function audit()
        {
        return $this->getOrder()->filter(function ($Order)
            {
            if ($Order->status_id != 0)
                fail("单据【{$Order->code}】{$Order->status->name}！必须【未审->审核】，审核失败！");

            $Order->details->filter(function ($item) use ($Order)
                {
                if ($item->status_id != 0)
                    fail("【{$Order->code}】一个子单据状态：{$item->status->name}！必须取消！");
                $item->status_id = 1;
                $item->save();
                });
            auditSave($Order);
            });
        }
    /**
     * Summary of noaudit
     * @return mixed
     */
    protected function noaudit()
        {
        return $this->getOrder()->filter(function ($Order)
            {
            if ($Order->status_id != 1)
                fail("单据【{$Order->code}】{$Order->status->name}！必须取消！");
            if ($Order->delivery_quantity != $Order->quantity)
                fail("单据【{$Order->code}】已做交货！无法反审核");
            if ($Order->plan_quantity != $Order->quantity)
                fail("单据【{$Order->code}】已做计划！无法反审核");

            $Order->details->filter(function ($item) use ($Order)
                {
                if ($item->status_id != 1)
                    fail("【{$Order->code}】一个子单据状态：{$item->status->name}！必须【已审->反审】，反审失败！");
                $item->status_id = 0;
                $item->save();
                });
            auditSave($Order, false);

            });
        }
    protected function finish()
        {
        return $this->getDetail()->filter(function ($Order)
            {
            if ($Order->status_id != 1)
                fail("单据【{$Order->main->code}】{$Order->status->name}！必须【审核->完结】，完结失败！");

            $Order['status_id'] = 2;
            $Order->save();
            });
        }
    protected function nofinish()
        {
        return $this->getDetail()->filter(function ($Order)
            {
            if ($Order->status_id != 2)
                fail("单据【{$Order->main->code}】{$Order->status->name}！必须【完结->取消完结】，取消完结失败！");

            $Order['status_id'] = 1;
            $Order->save();
            });
        }

    public function getDetail()
        {
        return $this->details->whereIn("id", $this->getRequestIds())->getList();
        }
    public function getOrder()
        {
        return $this->repository->whereIn("id", $this->getRequestIds())->getList();
        }
    protected function delete($request)
        {

        return $this->repository->whereIn("id", $this->getRequestIds())->get()->filter(function ($v)
            {
            if ($v->status_id == 1)
                fail("单据已审核！");
            //删除明细
            $v->details->filter(function ($detail)
                {
                $detail->delete();
                });
            $v->delete();
            });
        }

    public function printReport()
        {
        $data = $this->repository->relation()->whereIn("id", $this->getRequestIds())->get();
        // dd($data);
        return createReport($data->toArray());
        }
    }